package io.mft.yapi.util;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.mft.api.domain.Api;
import io.mft.commons.config.ConfigProvider;
import io.mft.dev.base.MFTRuntimeConfig;
import io.mft.dev.base.MFTRuntimeConfigProvider;
import io.mft.yapi.util.YApiMetaParser.YApiFunctionMeta;

public class YApiManager {
    private static YApiManager instance=new YApiManager();
    private static String URL= "http://"+ConfigProvider.getHostProgramConfigValue("yApi.ip", "10.0.209.216");
    private static Object YApiDs;


//    private static String PROJECT_ID = "9";
//    private static String GROUP_ID = "13";
    private YApiManager() {}
    public static YApiManager getInstance() {
        return instance;
    }
    private RequestParam requestParam = RequestParam.getInstance();
    private Logger logger = LoggerFactory.getLogger(YApiManager.class);

    
    public static String token(String systemKey) {
    	String token=YApiAccount.get().getStr("yApi.token");
    	return token;
	}
    //新增接口分类
    //输入参数：接口分类名称（YApiFunctionMeta.categoryName）、项目ID（project_id）
    private void addApiCategory(YApiMetaParser.YApiFunctionMeta meta) {
    	 String token=token(meta.getSystemKey());
        String categoryId = requestParam.getCatId(token,meta.categoryName);
        if(categoryId.equals("")){
            Map<String,Object> paramMap = new HashMap<>();
            String url =URL+"/api/interface/add_cat";
            paramMap.put("name",meta.categoryName);
            paramMap.put("project_id",requestParam.getProjectId(token));
            paramMap.put("token",token(meta.getSystemKey()));
            try{
                String result = HttpRequest.post(url).contentType("application/x-www-form-urlencoded").form(paramMap).execute().body();
                JSONObject jsonObject=JSONUtil.parseObj(result);
                if(jsonObject.getStr("errcode").equals("0")){
                    logger.info("新增接口分类\""+meta.categoryName+"\"成功！");
                }else{
                    logger.error("新增接口分类\""+meta.categoryName+"\"失败！");
                }
                //System.out.println(JSON.toJSONString(jsonObject, true));
            }catch (Exception e){
                logger.error("",e);
            }
        }else{
            logger.info("\""+meta.categoryName+"\"接口分类已存在！");
        }


    }

    //新增接口
    private void addApi(YApiMetaParser.YApiFunctionMeta meta){
        Map<String,Object> paramMap = new HashMap<>();
        String url =URL+"/api/interface/add";
        JSONObject data = new JSONObject();
        String token=token(meta.getSystemKey());
        String title = meta.funcNo+meta.interfaceName;
        paramMap.put("project_id",requestParam.getProjectId(token));
        paramMap.put("catid",requestParam.getCatId(token,meta.categoryName));
        paramMap.put("title",title);
        paramMap.put("path",requestParam.getPath(String.valueOf(meta.funcNo)));
        paramMap.put("method","GET");
        paramMap.put("token",token(meta.getSystemKey()));
        paramMap.put("res_body_is_json_schema",true);
        paramMap.put("res_body_type","json");
        paramMap.put("req_query",requestParam.setRequestQuery(meta.inYApiAttributeMetas));
        paramMap.put("res_body",requestParam.setResponseBody(meta.outYApiAttributeMetasMap));
//        System.out.println(requestParam.setRequestQuery(meta.inYApiAttributeMetas));
//        System.out.println(requestParam.setResponseBody(meta.outYApiAttributeMetasMap));
        data.putAll(paramMap);

        try{
            String result = HttpRequest.post(url).body(String.valueOf(data)).execute().body();
            JSONObject jsonObject=JSONUtil.parseObj(result);
            if(jsonObject.getStr("errcode").equals("0")){
                logger.info("新增接口\""+meta.funcNo+meta.interfaceName+"\"成功！");
            }else{
                logger.error("新增接口\""+meta.funcNo+meta.interfaceName+"\"失败！");
            }
//            logger.info("新增接口"+meta.funcNo+meta.interfaceName+"成功！");
//            System.out.println(JSON.toJSONString(jsonObject, true));
        }catch (Exception e){
            logger.error("",e);
        }
    }

    //更新接口
    private void updateApi(YApiMetaParser.YApiFunctionMeta meta){
    	 String token=token(meta.getSystemKey());
        String interfaceId = requestParam.getInterfaceId(token,meta.funcNo+meta.interfaceName);
        Map<String,Object> paramMap = new HashMap<>();
        String url =URL+"/api/interface/up";
        JSONObject data = new JSONObject();

        paramMap.put("token",token(meta.getSystemKey()));
        paramMap.put("id",Integer.parseInt(interfaceId));
        paramMap.put("res_body_is_json_schema",true);
        paramMap.put("res_body_type","json");
        paramMap.put("req_query",requestParam.setRequestQuery(meta.inYApiAttributeMetas));
        paramMap.put("res_body",requestParam.setResponseBody(meta.outYApiAttributeMetasMap));

        data.putAll(paramMap);
        try{
            String result = HttpRequest.post(url).body(String.valueOf(data)).execute().body();
            JSONObject jsonObject=JSONUtil.parseObj(result);
            if(jsonObject.getStr("errcode").equals("0")){
                logger.info("更新接口\""+meta.funcNo+meta.interfaceName+"\"成功！");
            }else{
                logger.error("更新接口\""+meta.funcNo+meta.interfaceName+"\"失败！");
            }

//            System.out.println(JSON.toJSONString(jsonObject, true));
        }catch (Exception e){
            logger.error("",e);
        }
    }

    private void addOrUpdateInterface(YApiMetaParser.YApiFunctionMeta meta){
        String interfaceId = requestParam.getInterfaceId(token(meta.getSystemKey()),meta.funcNo+meta.interfaceName);
        if(interfaceId.equals("")){
            addApi(meta);
        }else{
            updateApi(meta);
        }
    }


    public void addMockCase(YApiMetaParser.YApiFunctionMeta meta) throws IOException {
        HttpClient httpClient;
        HttpPost postMethod;
        HttpResponse response;
        String url =URL+"/api/plugin/advmock/case/save";

        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("code",200);
        paramMap.put("delay",0);
        paramMap.put("interface_id",requestParam.getInterfaceId(token(meta.getSystemKey()),meta.funcNo+meta.interfaceName));
        paramMap.put("name",meta.funcNo+meta.interfaceName);
        paramMap.put("project_id",requestParam.getProjectId(token(meta.getSystemKey())));
        paramMap.put("token",token(meta.getSystemKey()));
        paramMap.put("res_body",requestParam.setMockRequestBody(meta.outYApiAttributeMetasMap));
        if(requestParam.checkMockList(token(meta.getSystemKey()),paramMap.get("name").toString())){
            logger.info("Mock期望已存在！");
            requestParam.delMockCase(token(meta.getSystemKey()),paramMap.get("name").toString());
        }
        JSONObject data = new JSONObject();
        data.putAll(paramMap);

        try {
            httpClient = HttpClients.createDefault();
            postMethod = requestParam.setReqHeader(url);
            postMethod.addHeader("cookie",requestParam.getCookie());
            postMethod.setEntity(new StringEntity(String.valueOf(data),Charset.forName("utf-8")));
            response = httpClient.execute(postMethod);
            HttpEntity httpEntity = response.getEntity();
            String reponseContent = EntityUtils.toString(httpEntity);
            JSONObject jsonObject=JSONUtil.parseObj(reponseContent);
//            System.out.println(JSON.toJSONString(jsonObject,SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
//                    SerializerFeature.WriteDateUseDateFormat));
            if(jsonObject.getStr("errcode").equals("0")){
                logger.info("添加Mock期望成功！");
            }else{
                logger.error("添加Mock期望失败！");
            }
        } catch (Exception e) {
        	logger.error("", e);

        }
    }

	public void export(Api api) {
		try {
			
			YApiFunctionMeta meta=YApiMetaParser.parse(api);
			YApiManager.getInstance().addApiCategory(meta);
			YApiManager.getInstance().addOrUpdateInterface(meta);
			YApiManager.getInstance().addMockCase(meta);
		} catch (Exception e) {
			logger.error("", e);
		}

	}
	public void exportBySystemKey(String systemKey) {
		MFTRuntimeConfig config=MFTRuntimeConfigProvider.instance().provide();
		List<Api> apis=config.getApis();
		 for (Api api : apis) {
				if (api.getModule().getSystem().getKey().equals(systemKey)) {
					export(api);
				}
			}
	}
	public void export(String systemKey,String moduleKey) {
		MFTRuntimeConfig config=MFTRuntimeConfigProvider.instance().provide();
		List<Api> apis=config.getApis();
		 for (Api api : apis) {
				if (api.getModule().getAliasKey().equals(moduleKey)&&api.getModule().getSystem().getKey().equals(systemKey)) {
					export(api);
				}
			}
	}
	public void exportByApiKey(String apiKey) {
		MFTRuntimeConfig config=MFTRuntimeConfigProvider.instance().provide();
		List<Api> apis=config.getApis();
		for (Api api : apis) {
			if (api.getKey().equals(apiKey)) {
				export(api);
				break;
			}
		}
	}
}